package top.wshape1.rpc.starter;

import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Import;
import top.wshape1.rpc.JJRPC;
import top.wshape1.rpc.compress.Compressor;
import top.wshape1.rpc.compress.GzipCompressor;
import top.wshape1.rpc.consumer.tolerant.FailfastTolerantStrategy;
import top.wshape1.rpc.consumer.tolerant.FaultTolerantStrategy;
import top.wshape1.rpc.loadbalance.LoadBalance;
import top.wshape1.rpc.loadbalance.RoundRobinLoadBalance;
import top.wshape1.rpc.message.serializer.HessianSerializer;
import top.wshape1.rpc.message.serializer.Serializer;
import top.wshape1.rpc.registry.RpcRegistry;
import top.wshape1.rpc.registry.ZookeeperRegistry;
import top.wshape1.rpc.spring.ConsumerPostProcessor;

/**
 * @author Wshape1
 * @version 1.0
 * @description JJRPC AutoConfiguration
 * @since 2024-02-21
 */

// TODO 因为本Config加载顺序的问题，与core中的PostProcessor冲突，所以在一开始加载就会出错，导致JJRpcProperties和其它Registry等Bean还没加载就启动了JJRPC

@AutoConfiguration
@ConditionalOnClass(JJRPC.class)
@EnableConfigurationProperties(JJRpcProperties.class)
@Import({JJRpcBeanPostProcessor.class})
public class JJRpcAutoConfiguration {


    @Configuration(proxyBeanMethods = false)
    @DependsOn({"jjrpc-top.wshape1.rpc.starter.JJRpcProperties"})
    static class JJRpcSubAutoConfiguration {
        @Bean
        @ConditionalOnMissingBean
        public RpcRegistry registry() {
            return new ZookeeperRegistry();
        }

        @Bean
        @ConditionalOnMissingBean
        @ConditionalOnBean(ConsumerPostProcessor.class)
        public LoadBalance loadBalance() {
            return new RoundRobinLoadBalance();
        }

        @Bean
        @ConditionalOnMissingBean
        @ConditionalOnBean(ConsumerPostProcessor.class)
        public FaultTolerantStrategy faultTolerantStrategy() {
            return new FailfastTolerantStrategy();
        }

        @Bean
        @ConditionalOnMissingBean
        public Serializer serializer() {
            return new HessianSerializer();
        }

        @Bean
        @ConditionalOnMissingBean
        @ConditionalOnProperty(prefix = "jjrpc.compress", name = "enabled", havingValue = "true")
        public Compressor compressor() {
            return new GzipCompressor();
        }
    }

}
